package cn.edu.scau.cmi.hombio.service;

import cn.edu.scau.cmi.hombio.dao.EmployeeDAO;
import cn.edu.scau.cmi.hombio.dao.MedicineTakeDAO;
import cn.edu.scau.cmi.hombio.dao.MedicineTakeDetailDAO;
import cn.edu.scau.cmi.hombio.dao.TaskDAO;

import cn.edu.scau.cmi.hombio.domain.Employee;
import cn.edu.scau.cmi.hombio.domain.MedicineTake;
import cn.edu.scau.cmi.hombio.domain.MedicineTakeDetail;
import cn.edu.scau.cmi.hombio.domain.Task;

import java.util.List;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Transactional;

/**
 * Spring service that handles CRUD requests for MedicineTake entities
 * 
 */

@Service("MedicineTakeService")

@Transactional
public class MedicineTakeServiceImpl implements MedicineTakeService {

	/**
	 * DAO injected by Spring that manages Employee entities
	 * 
	 */
	@Autowired
	private EmployeeDAO employeeDAO;

	/**
	 * DAO injected by Spring that manages MedicineTake entities
	 * 
	 */
	@Autowired
	private MedicineTakeDAO medicineTakeDAO;

	/**
	 * DAO injected by Spring that manages MedicineTakeDetail entities
	 * 
	 */
	@Autowired
	private MedicineTakeDetailDAO medicineTakeDetailDAO;

	/**
	 * DAO injected by Spring that manages Task entities
	 * 
	 */
	@Autowired
	private TaskDAO taskDAO;

	/**
	 * Instantiates a new MedicineTakeServiceImpl.
	 *
	 */
	public MedicineTakeServiceImpl() {
	}

	/**
	 * Return all MedicineTake entity
	 * 
	 */
	@Transactional
	public List<MedicineTake> findAllMedicineTakes(Integer startResult, Integer maxRows) {
		return new java.util.ArrayList<MedicineTake>(medicineTakeDAO.findAllMedicineTakes(startResult, maxRows));
	}

	/**
	 * Save an existing Employee entity
	 * 
	 */
	@Transactional
	public MedicineTake saveMedicineTakeEmployeeByPharmacistId(Integer id, Employee related_employeebypharmacistid) {
		MedicineTake medicinetake = medicineTakeDAO.findMedicineTakeByPrimaryKey(id, -1, -1);
		Employee existingemployeeByPharmacistId = employeeDAO.findEmployeeByPrimaryKey(related_employeebypharmacistid.getId());

		// copy into the existing record to preserve existing relationships
		if (existingemployeeByPharmacistId != null) {
			existingemployeeByPharmacistId.setId(related_employeebypharmacistid.getId());
			existingemployeeByPharmacistId.setNumber(related_employeebypharmacistid.getNumber());
			existingemployeeByPharmacistId.setName(related_employeebypharmacistid.getName());
			existingemployeeByPharmacistId.setPassword(related_employeebypharmacistid.getPassword());
			existingemployeeByPharmacistId.setLogOn(related_employeebypharmacistid.getLogOn());
			existingemployeeByPharmacistId.setRfid(related_employeebypharmacistid.getRfid());
			existingemployeeByPharmacistId.setSex(related_employeebypharmacistid.getSex());
			existingemployeeByPharmacistId.setBirthday(related_employeebypharmacistid.getBirthday());
			existingemployeeByPharmacistId.setState(related_employeebypharmacistid.getState());
			existingemployeeByPharmacistId.setMemo(related_employeebypharmacistid.getMemo());
			related_employeebypharmacistid = existingemployeeByPharmacistId;
		}

		medicinetake.setEmployeeByPharmacistId(related_employeebypharmacistid);
		related_employeebypharmacistid.getMedicineTakesForPharmacistId().add(medicinetake);
		medicinetake = medicineTakeDAO.store(medicinetake);
		medicineTakeDAO.flush();

		related_employeebypharmacistid = employeeDAO.store(related_employeebypharmacistid);
		employeeDAO.flush();

		return medicinetake;
	}

	/**
	 * Save an existing Employee entity
	 * 
	 */
	@Transactional
	public MedicineTake saveMedicineTakeEmployeeByTakerId(Integer id, Employee related_employeebytakerid) {
		MedicineTake medicinetake = medicineTakeDAO.findMedicineTakeByPrimaryKey(id, -1, -1);
		Employee existingemployeeByTakerId = employeeDAO.findEmployeeByPrimaryKey(related_employeebytakerid.getId());

		// copy into the existing record to preserve existing relationships
		if (existingemployeeByTakerId != null) {
			existingemployeeByTakerId.setId(related_employeebytakerid.getId());
			existingemployeeByTakerId.setNumber(related_employeebytakerid.getNumber());
			existingemployeeByTakerId.setName(related_employeebytakerid.getName());
			existingemployeeByTakerId.setPassword(related_employeebytakerid.getPassword());
			existingemployeeByTakerId.setLogOn(related_employeebytakerid.getLogOn());
			existingemployeeByTakerId.setRfid(related_employeebytakerid.getRfid());
			existingemployeeByTakerId.setSex(related_employeebytakerid.getSex());
			existingemployeeByTakerId.setBirthday(related_employeebytakerid.getBirthday());
			existingemployeeByTakerId.setState(related_employeebytakerid.getState());
			existingemployeeByTakerId.setMemo(related_employeebytakerid.getMemo());
			related_employeebytakerid = existingemployeeByTakerId;
		}

		medicinetake.setEmployeeByTakerId(related_employeebytakerid);
		related_employeebytakerid.getMedicineTakesForTakerId().add(medicinetake);
		medicinetake = medicineTakeDAO.store(medicinetake);
		medicineTakeDAO.flush();

		related_employeebytakerid = employeeDAO.store(related_employeebytakerid);
		employeeDAO.flush();

		return medicinetake;
	}

	/**
	 */
	@Transactional
	public MedicineTake findMedicineTakeByPrimaryKey(Integer id) {
		return medicineTakeDAO.findMedicineTakeByPrimaryKey(id);
	}

	/**
	 * Delete an existing MedicineTake entity
	 * 
	 */
	@Transactional
	public void deleteMedicineTake(MedicineTake medicinetake) {
		medicineTakeDAO.remove(medicinetake);
		medicineTakeDAO.flush();
	}

	/**
	 * Delete an existing MedicineTakeDetail entity
	 * 
	 */
	@Transactional
	public MedicineTake deleteMedicineTakeMedicineTakeDetails(Integer medicinetake_id, Integer related_medicinetakedetails_id) {
		MedicineTakeDetail related_medicinetakedetails = medicineTakeDetailDAO.findMedicineTakeDetailByPrimaryKey(related_medicinetakedetails_id, -1, -1);

		MedicineTake medicinetake = medicineTakeDAO.findMedicineTakeByPrimaryKey(medicinetake_id, -1, -1);

		related_medicinetakedetails.setMedicineTake(null);
		medicinetake.getMedicineTakeDetails().remove(related_medicinetakedetails);

		medicineTakeDetailDAO.remove(related_medicinetakedetails);
		medicineTakeDetailDAO.flush();

		return medicinetake;
	}

	/**
	 * Save an existing MedicineTakeDetail entity
	 * 
	 */
	@Transactional
	public MedicineTake saveMedicineTakeMedicineTakeDetails(Integer id, MedicineTakeDetail related_medicinetakedetails) {
		MedicineTake medicinetake = medicineTakeDAO.findMedicineTakeByPrimaryKey(id, -1, -1);
		MedicineTakeDetail existingmedicineTakeDetails = medicineTakeDetailDAO.findMedicineTakeDetailByPrimaryKey(related_medicinetakedetails.getId());

		// copy into the existing record to preserve existing relationships
		if (existingmedicineTakeDetails != null) {
			existingmedicineTakeDetails.setId(related_medicinetakedetails.getId());
			existingmedicineTakeDetails.setTraceCode(related_medicinetakedetails.getTraceCode());
			existingmedicineTakeDetails.setBoxTraceCode(related_medicinetakedetails.getBoxTraceCode());
			existingmedicineTakeDetails.setCaseTraceCode(related_medicinetakedetails.getCaseTraceCode());
			existingmedicineTakeDetails.setIsBox(related_medicinetakedetails.getIsBox());
			related_medicinetakedetails = existingmedicineTakeDetails;
		} else {
			related_medicinetakedetails = medicineTakeDetailDAO.store(related_medicinetakedetails);
			medicineTakeDetailDAO.flush();
		}

		related_medicinetakedetails.setMedicineTake(medicinetake);
		medicinetake.getMedicineTakeDetails().add(related_medicinetakedetails);
		related_medicinetakedetails = medicineTakeDetailDAO.store(related_medicinetakedetails);
		medicineTakeDetailDAO.flush();

		medicinetake = medicineTakeDAO.store(medicinetake);
		medicineTakeDAO.flush();

		return medicinetake;
	}

	/**
	 * Load an existing MedicineTake entity
	 * 
	 */
	@Transactional
	public Set<MedicineTake> loadMedicineTakes() {
		return medicineTakeDAO.findAllMedicineTakes();
	}

	/**
	 * Delete an existing Task entity
	 * 
	 */
	@Transactional
	public MedicineTake deleteMedicineTakeTask(Integer medicinetake_id, Integer related_task_id) {
		MedicineTake medicinetake = medicineTakeDAO.findMedicineTakeByPrimaryKey(medicinetake_id, -1, -1);
		Task related_task = taskDAO.findTaskByPrimaryKey(related_task_id, -1, -1);

		medicinetake.setTask(null);
		related_task.getMedicineTakes().remove(medicinetake);
		medicinetake = medicineTakeDAO.store(medicinetake);
		medicineTakeDAO.flush();

		related_task = taskDAO.store(related_task);
		taskDAO.flush();

		taskDAO.remove(related_task);
		taskDAO.flush();

		return medicinetake;
	}

	/**
	 * Return a count of all MedicineTake entity
	 * 
	 */
	@Transactional
	public Integer countMedicineTakes() {
		return ((Long) medicineTakeDAO.createQuerySingleResult("select count(o) from MedicineTake o").getSingleResult()).intValue();
	}

	/**
	 * Delete an existing Employee entity
	 * 
	 */
	@Transactional
	public MedicineTake deleteMedicineTakeEmployeeByPharmacistId(Integer medicinetake_id, Integer related_employeebypharmacistid_id) {
		MedicineTake medicinetake = medicineTakeDAO.findMedicineTakeByPrimaryKey(medicinetake_id, -1, -1);
		Employee related_employeebypharmacistid = employeeDAO.findEmployeeByPrimaryKey(related_employeebypharmacistid_id, -1, -1);

		medicinetake.setEmployeeByPharmacistId(null);
		related_employeebypharmacistid.getMedicineTakesForPharmacistId().remove(medicinetake);
		medicinetake = medicineTakeDAO.store(medicinetake);
		medicineTakeDAO.flush();

		related_employeebypharmacistid = employeeDAO.store(related_employeebypharmacistid);
		employeeDAO.flush();

		employeeDAO.remove(related_employeebypharmacistid);
		employeeDAO.flush();

		return medicinetake;
	}

	/**
	 * Save an existing Task entity
	 * 
	 */
	@Transactional
	public MedicineTake saveMedicineTakeTask(Integer id, Task related_task) {
		MedicineTake medicinetake = medicineTakeDAO.findMedicineTakeByPrimaryKey(id, -1, -1);
		Task existingtask = taskDAO.findTaskByPrimaryKey(related_task.getId());

		// copy into the existing record to preserve existing relationships
		if (existingtask != null) {
			existingtask.setId(related_task.getId());
			existingtask.setTaskNumber(related_task.getTaskNumber());
			existingtask.setCreateTime(related_task.getCreateTime());
			existingtask.setStartTime(related_task.getStartTime());
			existingtask.setEndTime(related_task.getEndTime());
			existingtask.setMemo(related_task.getMemo());
			related_task = existingtask;
		}

		medicinetake.setTask(related_task);
		related_task.getMedicineTakes().add(medicinetake);
		medicinetake = medicineTakeDAO.store(medicinetake);
		medicineTakeDAO.flush();

		related_task = taskDAO.store(related_task);
		taskDAO.flush();

		return medicinetake;
	}

	/**
	 * Delete an existing Employee entity
	 * 
	 */
	@Transactional
	public MedicineTake deleteMedicineTakeEmployeeByTakerId(Integer medicinetake_id, Integer related_employeebytakerid_id) {
		MedicineTake medicinetake = medicineTakeDAO.findMedicineTakeByPrimaryKey(medicinetake_id, -1, -1);
		Employee related_employeebytakerid = employeeDAO.findEmployeeByPrimaryKey(related_employeebytakerid_id, -1, -1);

		medicinetake.setEmployeeByTakerId(null);
		related_employeebytakerid.getMedicineTakesForTakerId().remove(medicinetake);
		medicinetake = medicineTakeDAO.store(medicinetake);
		medicineTakeDAO.flush();

		related_employeebytakerid = employeeDAO.store(related_employeebytakerid);
		employeeDAO.flush();

		employeeDAO.remove(related_employeebytakerid);
		employeeDAO.flush();

		return medicinetake;
	}

	/**
	 * Save an existing MedicineTake entity
	 * 
	 */
	@Transactional
	public void saveMedicineTake(MedicineTake medicinetake) {
		MedicineTake existingMedicineTake = medicineTakeDAO.findMedicineTakeByPrimaryKey(medicinetake.getId());

		if (existingMedicineTake != null) {
			if (existingMedicineTake != medicinetake) {
				existingMedicineTake.setId(medicinetake.getId());
				existingMedicineTake.setTime(medicinetake.getTime());
				existingMedicineTake.setMemo(medicinetake.getMemo());
			}
			medicinetake = medicineTakeDAO.store(existingMedicineTake);
		} else {
			medicinetake = medicineTakeDAO.store(medicinetake);
		}
		medicineTakeDAO.flush();
	}
}
